package com.ruoyi.web.controller.system;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.aliyuncs.exceptions.ClientException;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.system.domain.GwContract;
import com.ruoyi.system.domain.GwEnterpriseInfo;
import com.ruoyi.system.dto.AliyunSmsDTO;
import com.ruoyi.system.mapper.GwEnterpriseInfoMapper;
import com.ruoyi.system.mapper.GwStaffMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.IGwContractDetailService;
import com.ruoyi.system.service.IGwContractService;
import com.ruoyi.system.utils.SendSmsUtil;
import com.tencent.essbasic.api.CreateSignUrls;
import com.tencent.essbasic.config.Config;
import com.tencentcloudapi.essbasic.v20210526.models.Agent;
import com.tencentcloudapi.essbasic.v20210526.models.CreateSignUrlsResponse;
import com.tencentcloudapi.essbasic.v20210526.models.UserInfo;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

import static com.tencent.essbasic.callback.CallbackAes.aesDecrypt;

@RestController
@RequestMapping("/api/esign/callback")
public class TencentESignCallbackController {

    // 测试环境
//    private static final String API_KEY = "BC0BD66475664E879C3882AB7870EC4B";

    // 线上环境
    private static final String API_KEY = "FEA606101116442FB21E36791DD0B9AE";

    @Resource
    private IGwContractService gwContractService;
    @Resource
    private GwStaffMapper gwStaffMapper;
    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    private GwEnterpriseInfoMapper gwEnterpriseInfoMapper;
    @Resource
    private IGwContractDetailService gwContractDetailService;
    @Resource
    private SendSmsUtil sendSmsUtil;

    /**
     * 腾讯电子签回调接口
     *
     * @param callbackData 回调数据
     * @return 返回处理结果
     */
    @PostMapping
    public String handleCallback(@RequestBody String callbackData) {

        System.out.println("callbackData: " + callbackData);

        try {
            // 解析回调数据
            JSONObject dataObj = JSON.parseObject(callbackData);

            //解密
            String encrypt = dataObj.getString("encrypt");
            byte[] key = API_KEY.getBytes();
            byte[] origData = aesDecrypt(encrypt.getBytes(StandardCharsets.UTF_8), key);
            String decryptData = new String(origData, StandardCharsets.UTF_8);
            JSONObject json = JSON.parseObject(decryptData);

            String eventType = json.getString("MsgType");

            // 根据事件类型进行不同处理
            switch (eventType) {
                case "FlowStatusChange":
                    handleFlowStatusChange(json);
                    break;
                case "TemplateAdd":
                    handleTemplateAdd(json);
                    break;
                case "OrgOpenTsignBiz":
                    handleOrgOpenTsignBiz(json);
                    break;
                case "VerifyStaffInfo":
                    handleVerifyStaffInfo(json);
                    break;
                // 可以添加更多事件类型处理
                default:
                    System.out.println("未知事件类型: " + eventType);
            }

            return generateResponse(true, "处理成功");
        } catch (Exception e) {
            e.printStackTrace();
            return generateResponse(false, "处理异常: " + e.getMessage());
        }
    }

    /**
     * 验证签名
     */
    private boolean verifySignature(String signature, String timestamp, String nonce, String data) {
        try {
            // 生成待签名字符串
            String stringToSign = timestamp + nonce + data;

            // 使用HMAC-SHA256算法生成签名
            Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
            SecretKeySpec secret_key = new SecretKeySpec(API_KEY.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
            sha256_HMAC.init(secret_key);

            // 对结果进行Base64编码
            String encodedSignature = Base64.getEncoder().encodeToString(sha256_HMAC.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8)));

            // 比较签名
            return encodedSignature.equals(signature);
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 生成响应
     */
    private String generateResponse(boolean success, String message) {
        JSONObject response = new JSONObject();
        response.put("code", success ? 0 : 1);
        response.put("message", message);
        return response.toJSONString();
    }

    /**
     * 处理流程状态改变事件
     */
    private void handleFlowStatusChange(JSONObject data) throws ClientException {
        System.out.println("流程状态改变: " + data.toJSONString());
        // 这里添加业务逻辑，如归档文件、更新业务状态等
        JSONObject MsgData = data.getJSONObject("MsgData");

        String FlowId = MsgData.getString("FlowId");
        String FlowStatus = MsgData.getString("FlowStatus");
        String FlowMessage = MsgData.getString("FlowMessage");

        GwContract query = gwContractService.selectGwContractByContractId(FlowId);

        //获取公司信息
        GwEnterpriseInfo gwEnterpriseInfo = gwEnterpriseInfoMapper.selectGwEnterpriseInfoById(query.getCompanyId());

        //获取签署地址url
        String s = "";
        try {
            //String s = DescribeFileUrls.describeFileUrls(FlowId);
            SysUser sysUser = sysUserMapper.selectUserByPhone(gwEnterpriseInfo.getPhone());
            Agent agent = new Agent();
            UserInfo userInfo = new UserInfo();
            agent.setAppId(Config.AppId);
            agent.setProxyAppId(Config.ProxyAppId);
            agent.setProxyOrganizationOpenId(gwEnterpriseInfo.getSignOpenId());
            userInfo.setOpenId(sysUser.getSignOpenId());
            agent.setProxyOperator(userInfo);

            String[] flowIds = new String[1];
            flowIds[0] = FlowId;
            CreateSignUrlsResponse signUrls = CreateSignUrls.createSignUrls(flowIds, agent, null);
            s = signUrls.getSignUrlInfos()[0].getSignUrl();
        } catch (Exception e) {
            System.out.println(e.toString());
        }

        //更新主表
        GwContract contract = new GwContract();
        contract.setId(query.getId());
        contract.setStatus(FlowStatus);
        contract.setStatusName(FlowMessage);
        contract.setSignLink(s);
        //contract.setUpdateBy("腾讯");
        gwContractService.updateGwContractCallback(contract);

        JSONArray FlowApproverInfo = MsgData.getJSONArray("FlowApproverInfo");

        for (Object o : FlowApproverInfo) {
            JSONObject jsonObject = JSON.parseObject(o.toString());
//            String ApproveName = jsonObject.getString("ApproveName");
            String PhoneNumber = jsonObject.getString("PhoneNumber");
            String ApproveStatus = jsonObject.getString("ApproveStatus");
            String ApproveMessage = jsonObject.getString("ApproveMessage");
            int i = gwContractDetailService.updateStatusByContractIdAndNameAndTel(query.getId() + "", PhoneNumber, ApproveStatus, ApproveMessage);

            //2025.7.24取消 通过模板发起 && 状态INIT 发送短信
//            if ("INIT".equals(FlowStatus) && "平台模板".equals(query.getTemplateType()) && i > 0) {
//                //【Gowork】[企业名称]发起[合同名称]的签署流程，请尽快完成签署。[电子签的H5链接]
//                AliyunSmsDTO aliyunSmsDTO = new AliyunSmsDTO();
//                aliyunSmsDTO.setPhoneNumbers(PhoneNumber);
//                //SMS_490385118 正式   SMS_490445126 测试
//                aliyunSmsDTO.setTemplateCode("SMS_490385118");
//                JSONObject json = new JSONObject();
//                //设置模板参数
//                json.put("company", gwEnterpriseInfo.getEnterpriseName());
//                json.put("contract", query.getContractName());
//                String[] split = s.split("/");
//                json.put("code", split[split.length - 1]);
//                aliyunSmsDTO.setTemplateParam(json.toJSONString());
//                sendSmsUtil.sendSms(aliyunSmsDTO);
//            }
        }

        if ("ALL".equals(FlowStatus) && "员工关系".equals(query.getContractType())) {
            // 更新员工合同到期时间
            gwStaffMapper.updateGwStaffByContractId(query.getId() + "");
        }

    }

    private void handleOrgOpenTsignBiz(JSONObject data) {
        System.out.println("企业开通电子签服务: " + data.toJSONString());
        JSONObject MsgData = data.getJSONObject("MsgData");
        String ProxyOrganizationOpenId = MsgData.getString("ProxyOrganizationOpenId");
        String ProxyOperatorOpenId = MsgData.getString("ProxyOperatorOpenId");
        String LegalOpenId = MsgData.getString("LegalOpenId");

        sysUserMapper.updateCertificationStatus(ProxyOrganizationOpenId + "," + ProxyOperatorOpenId + "," + LegalOpenId);
        gwEnterpriseInfoMapper.updateCertificationStatus(ProxyOrganizationOpenId + "," + ProxyOperatorOpenId + "," + LegalOpenId);
    }

    private void handleVerifyStaffInfo(JSONObject data) {
        System.out.println("员工加入企业通知: " + data.toJSONString());
        JSONObject MsgData = data.getJSONObject("MsgData");
        String ProxyOrganizationOpenId = MsgData.getString("ProxyOrganizationOpenId");
        String ProxyOperatorOpenId = MsgData.getString("ProxyOperatorOpenId");
        sysUserMapper.updateCertificationStatus(ProxyOrganizationOpenId + "," + ProxyOperatorOpenId);
        gwEnterpriseInfoMapper.updateCertificationStatus(ProxyOrganizationOpenId + "," + ProxyOperatorOpenId);
        // todo 有可能角色权限
    }

    /**
     * 模板新增事件
     */
    private void handleTemplateAdd(JSONObject data) {
        System.out.println("模板新增: " + data.toJSONString());
//        {
//            "MsgId": "yDCVGUUckpwl6zn2UuGjzgvvGIxNNARh",
//                "MsgType": "TemplateAdd",
//                "MsgVersion": "ThirdPartyApp",
//                "MsgData": {
//            "ApplicationId": "yDCVGUAckpwll4vuUxRbCLx81uTHHOT6",
//                    "ProxyOrganizationOpenId": "essbasic-org-openid",
//                    "ProxyOperatorOpenId": "operator-openid",
//                    "TemplateId": "yDCVGBBckpwll4vuUxRbCLx81uTHAOH5",
//                    "TemplateName": "采购协议",
//                    "CreateTime": 1709629136,
//                    "ChannelTemplateId": "yDw8XUUckpkfomsgU7sFQE70AJBqn3Ch",
//                    "ChannelTemplateName": "采购协议",
//                    "SaveType": 0,
//                    "TemplateVersion": "20231009001",
//                    "UserData": "eyJDb21lRnJvbSI6Inh4eCJ9"
//         }
//        }
    }

    /**
     * 处理文档签署成功事件
     */
    private void handleDocumentSignSuccess(JSONObject data) {
        System.out.println("文档签署成功: " + data.toJSONString());
        // 这里添加业务逻辑，如更新订单状态、发送通知等
    }

    /**
     * 处理文档签署失败事件
     */
    private void handleDocumentSignFail(JSONObject data) {
        System.out.println("文档签署失败: " + data.toJSONString());
        // 这里添加业务逻辑，如记录失败原因、通知相关人员等
    }

    /**
     * 处理流程完成事件
     */
    private void handleFlowFinish(JSONObject data) {
        System.out.println("流程完成: " + data.toJSONString());
        // 这里添加业务逻辑，如归档文件、更新业务状态等
    }

    /**
     * 处理流程取消事件
     */
    private void handleFlowCancel(JSONObject data) {
        System.out.println("流程取消: " + data.toJSONString());
        // 这里添加业务逻辑，如通知相关人员、更新业务状态等
    }

}